﻿using Microsoft.SqlServer.Management.Smo;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;

namespace JsonToSql
{
    /// <summary>
    /// Cell created from json text format 
    /// </summary>
    public class JsonCell
    {
        /// <summary>
        /// Maximum length of countable type
        /// </summary>
        public int? MaxLength
        {
            get
            {
                if(ValueType == typeof(string))
                {
                    return Value.ToString().Length;
                }
                return null;
            }
            
        }
        private object value;
        /// <summary>
        /// Value of cell
        /// </summary>
        public object Value
        {
            get
            {
                if (value==null)
                {
                    value = this.token.ToObject(getValueType());
                }
                return value;
            }
        }
        /// <summary>
        /// Value type using for calculating length
        /// </summary>
        public Type ValueType
        {
            get
            {
                return getValueType();
            }
        }
        private SqlDataType dataType;
        /// <summary>
        /// Data type using in sql creation queries
        /// </summary>
        public SqlDataType DataType
        {
            get
            {
                if (dataType == SqlDataType.None)
                {
                    dataType = getSqlDataType();
                }
                return dataType;
            }
        }
        private SqlDataType getSqlDataType()
        {
            switch (this.token.Type)
            {
                case JTokenType.Integer: return SqlDataType.Int;
                case JTokenType.Boolean: return SqlDataType.Bit;
                case JTokenType.Date: return SqlDataType.DateTime;
                case JTokenType.Float: return SqlDataType.Float;
                case JTokenType.Guid: return SqlDataType.UniqueIdentifier;
                case JTokenType.TimeSpan: return SqlDataType.Timestamp;
                default: return SqlDataType.NVarChar;
            }
        }
        private Type getValueType()
        {
            switch (this.token.Type)
            {
                case JTokenType.Integer: return typeof(int);
                case JTokenType.Boolean: return typeof(bool);
                case JTokenType.Date: return typeof(DateTime);
                case JTokenType.Float: return typeof(double);
                case JTokenType.Guid: return typeof(Guid);
                case JTokenType.Null: return typeof(System.DBNull);
                case JTokenType.TimeSpan: return typeof(TimeSpan);
                case JTokenType.Array:
                    return typeof(List<object>);
                default: return typeof(string);
            }
        }
       
        private string name;
        /// <summary>
        /// Name of the cell, it is name of column
        /// </summary>
        public string Name
        {
            get
            {
                if(name==null)
                {
                    name = System.IO.Path.GetExtension(token.Path).Substring(1);
                }
                return name;
            }
        }
        private JToken token;
        private JsonRow parent;
        /// <summary>
        /// Parent row
        /// </summary>
        public JsonRow Parent
        {
            get
            {
                return parent;
            }
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="token">Token from json parsing</param>
        /// <param name="parent">Parent row of cell </param>
        public JsonCell(JToken token, JsonRow parent)
        {
            this.token = token;
            this.parent = parent;
            this.Parent.Parent.AddColumn(this);
            
        }
        
    }
}
